package com.voja.salonschedule;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.voja.AndroidUtils.Application;
import com.voja.AndroidUtils.Application.Click;
import com.voja.AndroidUtils.Application.Command;
import com.voja.AndroidUtils.Application.CommandWrapper;
import com.voja.salonschedule.customers.Adapter;
import com.voja.salonschedule.data.Customer;
import com.voja.salonschedule.data.Customer.CustomerItem;
import com.voja.salonschedule.data.Event;
import com.voja.salonschedule.data.Event.EventItem;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Pair;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class Events extends BaseChildActivity {
	Context context;
	
	Event modelEvent;
	EventItem itemEvent;
	public static int itemId;
	
	public Customer modelCustomer;
	CustomerItem itemCustomer;
	
	public static final int DATE_DIALOG_ID = 100;
	public static final int TIME_DIALOG_ID = 101;
	
	Resources res;
	SharedPreferences prefs;
	public static ArrayList<CustomerItem> customers;
	Map<String, Double> prices = new HashMap<String, Double>();
	
	Bundle extras;
	String action;
	
	private class ServiceChangedListener implements OnItemSelectedListener {
		
		Map<String, Double> prices;
		EditText 			txtPrice;
		
		public ServiceChangedListener(Map<String, Double> prices, EditText txtPrice) {
			this.prices = prices;
			this.txtPrice = txtPrice;
		}

		@Override
		public void onItemSelected(AdapterView<?> av, View v, int position, long id) {
			String service = av.getItemAtPosition(position).toString();
			if (this.prices.containsKey(service)) {
				double price = this.prices.get(service);
				txtPrice.setText("" + price);
			}
		}

		@Override
		public void onNothingSelected(AdapterView<?> av) {
			
		}
		
	};
	
	@Override
	public void onCreate(Bundle instance) {
		super.onCreate(instance);
		
		context = getApplicationContext();
		Application.setContext(this);
		Application.DEFAULT_MESSAGE_TITLE = getResources().getString(R.string.app_name);
		
		res   = getResources();
		prefs = PreferenceManager.getDefaultSharedPreferences(context);
		
		modelEvent = new Event(context);
		modelCustomer = new Customer(context);
	}
	
	@Override
	public void onResume() {
	    super.onResume();
	    
	    extras = getIntent().getExtras();
        action = extras.getString("action");
	    
	    if (prefs.getString(Settings.SERVICES_KEY, Settings.SERVICES_DEFAULT) == Settings.SERVICES_DEFAULT) {
            Click click = new Click("OK", new CommandWrapper(new Command() {
                @Override
                public void execute() {
                    Intent intent = new Intent(context, Services.class);
                    startActivity(intent);
                }
            }));
            Application.alert(res.getString(R.string.msgEmptyServices), click);
        } else {
            
            loadCustomers();
            loadPrices();
            
            // ADD EVENT
            if (action.equals("add")) {
                String date = extras.getString("date");
                String time = extras.getString("time");
                
                if (date.length()>0 && time.length()>0) {
                    addEvent(date, time);
                } else {
                    addEvent();
                }
                
            // EDIT EVENT
            } else if (action.equals("edit")) {
                int eventId = Integer.parseInt(extras.getString("id"));
                editEvent(eventId);
            
            // DELETE EVENT
            } else if (action.equals("delete")) {
                int eventId = Integer.parseInt(extras.getString("id"));
                deleteEvent(eventId);
            }
        }
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.events, menu);
        
        if (action.equals("add")) {
            menu.findItem(R.id.menuDelete).setVisible(false);
        }
        
	    return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case R.id.menuSave:
	        save();
	        break;
	        
	    case R.id.menuDelete:
	        delete();
	        break;
	    }
	    
	    return super.onOptionsItemSelected(item);
	}
	
	private void loadCustomers() {
		ArrayList<CustomerItem> customers = modelCustomer.getCustomers("");
		Events.customers = new ArrayList<CustomerItem>();
		for (int i=0; i<customers.size(); i++) {
			Events.customers.add(customers.get(i));
		}
	}
	
	private void loadPrices() {
		prices = new HashMap<String, Double>();
		ArrayList<Pair<String,String>> dbPrices = modelEvent.getLastPrices();
		double p;
		for (int i=0; i<dbPrices.size(); i++) {
			try {
				p = Double.parseDouble(dbPrices.get(i).second);
			} catch (NumberFormatException e) {
				p = 0;
			}
			if (p>0) {
				prices.put(dbPrices.get(i).first, p);
			}
		}
	}
	
	public void addEvent() {
		addEvent(null, null);
	}
	public void addEvent(String date, String time) {
		setContentView(R.layout.event_form);
		
		setTitle(getResources().getString(R.string.CreateEvent));
		itemEvent = modelEvent.new EventItem();
		if (date != null && time != null) {
			int step = Integer.parseInt(prefs.getString(Settings.TIME_STEP_KEY, Settings.TIME_STEP_DEFAULT));
			String time_end = Index.min2time(Index.time2min(time) + step);
			try {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
				itemEvent.date_start = sdf.parse(date+" "+time);
				itemEvent.date_end   = sdf.parse(date+" "+time_end);
			} catch (ParseException e) {
				Application.alert(res.getString(R.string.msgInvalidDateFormat));
			}
		}
		
		populateForm(itemEvent);
	}
	
	public void editEvent(int eventId) {
		setContentView(R.layout.event_form);
		
		setTitle(getResources().getString(R.string.EditEvent));
		EventItem event = modelEvent.findById(eventId);
		
		itemEvent = event;
		populateForm(event);
	}
	
	private void save() {
		boolean valid = true;
		
		try {
			EditText txtId = (EditText)findViewById(R.id.txtId);
			itemEvent.id = 0;
			if (txtId.getText() != null) {
				itemEvent.id = Integer.parseInt(txtId.getText().toString());
			}
			
			AutoCompleteTextView txtCustomer = (AutoCompleteTextView)findViewById(R.id.txtCustomer);
			itemEvent.customer        = txtCustomer.getText().toString().trim();
			if (itemEvent.customer.length() == 0) {
				throw new RuntimeException(res.getString(R.string.msgCustomerIsRequired));
			}
			
			Spinner spnService = (Spinner)findViewById(R.id.spnService);
			itemEvent.service       = spnService.getSelectedItem().toString();
			
			EditText txtPrice = (EditText)findViewById(R.id.txtPrice);
			String price	  = txtPrice.getText().toString();
			price 			  = price.equals("") ? "0" : price;
			itemEvent.price        = Double.parseDouble(price);
			
			EditText txtNotes = (EditText)findViewById(R.id.txtNotes);
			itemEvent.notes        = txtNotes.getText().toString();
			
			EditText txtDate 	 = (EditText)findViewById(R.id.txtDate);
			String date 		 = txtDate.getText().toString();
			itemEvent.date_start = getSpinnerDatetime(R.id.spinTimeStart, date);
			itemEvent.date_end   = getSpinnerDatetime(R.id.spinTimeEnd, date);
			
		} catch (ParseException pe) {
			valid = false;
			Application.alert(res.getString(R.string.msgInvalidDateFormat));
		} catch (RuntimeException re) {
			valid = false;
			Application.alert(res.getString(R.string.Error) + ": " + re.getMessage());
		}
		
		if (valid) {
			if (modelEvent.save(itemEvent)) {
				itemCustomer = new CustomerItem();
				itemCustomer.name = itemEvent.customer;
				modelCustomer.save(itemCustomer);
				
				finish();
				Widget.context = context;
				Widget.updateWidgets();
			} else {
				Application.alert(res.getString(R.string.Error) + ": " + modelEvent.getError());
			}
		}
	}
	
	private void delete() {
		EditText txtId = (EditText)findViewById(R.id.txtId);
		int id = Integer.parseInt(txtId.getText().toString());
		deleteEvent(id);
	}
	
	public void deleteEvent(int eventId) {
		itemId = eventId;
		modelEvent.delete(itemId);
		Widget.updateWidgets();
		finish();
	}
	
	private void populateForm(EventItem event) {
		EditText txtId = (EditText)findViewById(R.id.txtId);
		txtId.setText(""+event.id);
				
		// Customer
		AutoCompleteTextView txtCustomer = (AutoCompleteTextView)findViewById(R.id.txtCustomer);
		txtCustomer.setThreshold(1);
		txtCustomer.setText(event.customer);
		ArrayAdapter<CustomerItem> adapterCustomer = new Adapter(this, R.layout.customer_list_item, customers, "");
        txtCustomer.setAdapter(adapterCustomer);
		
        // Date
		EditText txtDate = (EditText)findViewById(R.id.txtDate);
		txtDate.setText(Event.dateFormat2.format(event.date_start));
		TextView txtDateLabel = (TextView)findViewById(R.id.txtDateLabel);
		txtDateLabel.setText(Event.dateFormat4.format(event.date_start));
		
		// Time
		Spinner spinTimeStart = (Spinner)findViewById(R.id.spinTimeStart);
		Spinner spinTimeEnd   = (Spinner)findViewById(R.id.spinTimeEnd);
		populateTimeSpinner(spinTimeStart, "start", event.date_start);
		populateTimeSpinner(spinTimeEnd,   "end",   event.date_end);
		
		// Price
		EditText txtPrice = (EditText)findViewById(R.id.txtPrice);
		txtPrice.setText("" + (event.price>0 ? event.price : ""));
		
		// Notes
		EditText txtNotes = (EditText)findViewById(R.id.txtNotes);
		txtNotes.setText(event.notes);
		
		// services
		Spinner spnService  = (Spinner)findViewById(R.id.spnService);
		String[] services   = getServices();
		java.util.Arrays.sort(services);
		
		// services data adapter
		ArrayAdapter<String> adapterService = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, services);
		adapterService.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spnService.setAdapter(adapterService);
		
		// services onItemSelected listener
		spnService.setOnItemSelectedListener(new ServiceChangedListener(prices, txtPrice));
		
		// select service
		for (int i=0; i<spnService.getCount(); i++) {
			if (services[i].compareTo(event.service) == 0) {
				spnService.setSelection(i);
				break;
			}
		}
	}
	
	private String[] getServices() {
		String prefServices = prefs.getString(Settings.SERVICES_KEY, Settings.SERVICES_DEFAULT);
		return prefServices.split(Settings.SERVICES_SPLIT);
	}
	
	private void populateTimeSpinner(Spinner s, String type, Date date) {
		int workStart = Integer.parseInt(prefs.getString(Settings.WORK_HOURS_START_KEY,
														 Settings.WORK_HOURS_DEFAULT_START));
		int workEnd   = Integer.parseInt(prefs.getString(Settings.WORK_HOURS_END_KEY,
														 Settings.WORK_HOURS_DEFAULT_END));
		int workStep  = Integer.parseInt(prefs.getString(Settings.TIME_STEP_KEY,
														 Settings.TIME_STEP_DEFAULT));
		
		int start = Index.time2min(workStart+":00");
		int end   = Index.time2min(workEnd+":00");
		
		if (type == "end") {
			start += workStep;
		}
		
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
		for (int i=start; i<=end; i+=workStep) {
			adapter.add(Index.min2time(i));
		}
		s.setAdapter(adapter);
		s.setSelection(adapter.getPosition(Event.timeFormat.format(date)));
	}
	
	private Date getSpinnerDatetime(int id, String date) throws ParseException {
		Spinner spinTimeStart = (Spinner)findViewById(id);
		String timeStart	  = spinTimeStart.getSelectedItem().toString();
		SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
		return sdf.parse(date + " " + timeStart);
	}
}
